home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d927.lha / Telnet / src / utilities.c < prev   
C/C++ Source or Header  |  1993-10-07  |  16KB  |  696 lines

  1. /*
  2.  * Copyright (c) 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)utilities.c    5.1 (Berkeley) 9/14/90";
  22. #endif /* not lint */
  23.  
  24. #define    TELOPTS
  25. #define    TELCMDS
  26. #include <arpa/telnet.h>
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29. #ifdef AMI_TCP
  30. #include <bsdsocket.h>
  31. #else
  32. #include <ss/socket.h>
  33. #endif
  34.  
  35. #include <ctype.h>
  36.  
  37. #include "general.h"
  38.  
  39. #include "fdset.h"
  40.  
  41. #include "ring.h"
  42.  
  43. #include "defines.h"
  44.  
  45. #include "externs.h"
  46.  
  47. FILE    *NetTrace = 0;        /* Not in bss, since needs to stay */
  48. int    prettydump;
  49.  
  50. /*
  51.  * upcase()
  52.  *
  53.  *    Upcase (in place) the argument.
  54.  */
  55.  
  56. void
  57. upcase(argument)
  58. register char *argument;
  59. {
  60.     register int c;
  61.  
  62.     while ((c = *argument) != 0) {
  63.     if (islower(c)) {
  64.         *argument = toupper(c);
  65.     }
  66.     argument++;
  67.     }
  68. }
  69.  
  70. int
  71. SetSockOpt(fd, level, option, yesno)
  72. int
  73.     fd,
  74.     level,
  75.     option,
  76.     yesno;
  77. {
  78.     return setsockopt(fd, level, option,
  79.                 (char *)&yesno, sizeof yesno);
  80. }
  81.  
  82. /*
  83.  * The following are routines used to print out debugging information.
  84.  */
  85.  
  86. unsigned char NetTraceFile[256] = "(standard output)";
  87.  
  88. void
  89. SetNetTrace(file)
  90. register char *file;
  91. {
  92.     if (NetTrace && NetTrace != stdout)
  93.     fclose(NetTrace);
  94.     if (file  && (strcmp(file, "-") != 0)) {
  95.     NetTrace = fopen(file, "w");
  96.     if (NetTrace) {
  97.         strcpy(NetTraceFile, file);
  98.         return;
  99.     }
  100.     fprintf(stderr, "Cannot open %s.\n", file);
  101.     }
  102.     NetTrace = stdout;
  103.     strcpy(NetTraceFile, "(standard output)");
  104. }
  105.  
  106. void
  107. Dump(direction, buffer, length)
  108. char    direction;
  109. char    *buffer;
  110. int    length;
  111. {
  112. #   define BYTES_PER_LINE    32
  113. #ifndef min
  114. #   define min(x,y)    ((x<y)? x:y)
  115. #endif
  116.     char *pThis;
  117.     int offset;
  118.     extern pettydump;
  119.  
  120.     offset = 0;
  121.  
  122.     while (length) {
  123.     /* print one line */
  124.     fprintf(NetTrace, "%c 0x%x\t", direction, offset);
  125.     pThis = buffer;
  126.     if (prettydump) {
  127.         buffer = buffer + min(length, BYTES_PER_LINE/2);
  128.         while (pThis < buffer) {
  129.         fprintf(NetTrace, "%c%.2x",
  130.             (((*pThis)&0xff) == 0xff) ? '*' : ' ',
  131.             (*pThis)&0xff);
  132.         pThis++;
  133.         }
  134.         length -= BYTES_PER_LINE/2;
  135.         offset += BYTES_PER_LINE/2;
  136.     } else {
  137.         buffer = buffer + min(length, BYTES_PER_LINE);
  138.         while (pThis < buffer) {
  139.         fprintf(NetTrace, "%.2x", (*pThis)&0xff);
  140.         pThis++;
  141.         }
  142.         length -= BYTES_PER_LINE;
  143.         offset += BYTES_PER_LINE;
  144.     }
  145.     if (NetTrace == stdout) {
  146.         fprintf(NetTrace, "\r\n");
  147.     } else {
  148.         fprintf(NetTrace, "\n");
  149.     }
  150.     if (length < 0) {
  151.         fflush(NetTrace);
  152.         return;
  153.     }
  154.     /* find next unique line */
  155.     }
  156.     fflush(NetTrace);
  157. }
  158.  
  159.  
  160. void
  161. printoption(direction, fmt, option)
  162.     char *direction, *fmt;
  163.     int option;
  164. {
  165.     if (!showoptions)
  166.         return;
  167.     fprintf(NetTrace, "%s ", direction);
  168.     if (TELOPT_OK(option))
  169.         fprintf(NetTrace, "%s %s", fmt, TELOPT(option));
  170.     else if (TELCMD_OK(option))
  171.         fprintf(NetTrace, "%s %s", fmt, TELCMD(option));
  172.     else
  173.         fprintf(NetTrace, "%s %d", fmt, option);
  174.     if (NetTrace == stdout)
  175.         fprintf(NetTrace, "\r\n");
  176.     else
  177.         fprintf(NetTrace, "\n");
  178.     return;
  179. }
  180.  
  181. optionstatus()
  182. {
  183.     register int i;
  184.     extern char will_wont_resp[], do_dont_resp[];
  185.  
  186.     for (i = 0; i < 256; i++) {
  187.     if (do_dont_resp[i]) {
  188.         if (TELOPT_OK(i))
  189.         printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
  190.         else if (TELCMD_OK(i))
  191.         printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
  192.         else
  193.         printf("resp DO_DONT %d: %d\n", i,
  194.                 do_dont_resp[i]);
  195.         if (my_want_state_is_do(i)) {
  196.         if (TELOPT_OK(i))
  197.             printf("want DO   %s\n", TELOPT(i));
  198.         else if (TELCMD_OK(i))
  199.             printf("want DO   %s\n", TELCMD(i));
  200.         else
  201.             printf("want DO   %d\n", i);
  202.         } else {
  203.         if (TELOPT_OK(i))
  204.             printf("want DONT %s\n", TELOPT(i));
  205.         else if (TELCMD_OK(i))
  206.             printf("want DONT %s\n", TELCMD(i));
  207.         else
  208.             printf("want DONT %d\n", i);
  209.         }
  210.     } else {
  211.         if (my_state_is_do(i)) {
  212.         if (TELOPT_OK(i))
  213.             printf("     DO   %s\n", TELOPT(i));
  214.         else if (TELCMD_OK(i))
  215.             printf("     DO   %s\n", TELCMD(i));
  216.         else
  217.             printf("     DO   %d\n", i);
  218.         }
  219.     }
  220.     if (will_wont_resp[i]) {
  221.         if (TELOPT_OK(i))
  222.         printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
  223.         else if (TELCMD_OK(i))
  224.         printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
  225.         else
  226.         printf("resp WILL_WONT %d: %d\n",
  227.                 i, will_wont_resp[i]);
  228.         if (my_want_state_is_will(i)) {
  229.         if (TELOPT_OK(i))
  230.             printf("want WILL %s\n", TELOPT(i));
  231.         else if (TELCMD_OK(i))
  232.             printf("want WILL %s\n", TELCMD(i));
  233.         else
  234.             printf("want WILL %d\n", i);
  235.         } else {
  236.         if (TELOPT_OK(i))
  237.             printf("want WONT %s\n", TELOPT(i));
  238.         else if (TELCMD_OK(i))
  239.             printf("want WONT %s\n", TELCMD(i));
  240.         else
  241.             printf("want WONT %d\n", i);
  242.         }
  243.     } else {
  244.         if (my_state_is_will(i)) {
  245.         if (TELOPT_OK(i))
  246.             printf("     WILL %s\n", TELOPT(i));
  247.         else if (TELCMD_OK(i))
  248.             printf("     WILL %s\n", TELCMD(i));
  249.         else
  250.             printf("     WILL %d\n", i);
  251.         }
  252.     }
  253.     }
  254.  
  255. }
  256.  
  257. char *slcnames[] = { SLC_NAMES };
  258.  
  259. void
  260. printsub(direction, pointer, length)
  261. char    direction;        /* '<' or '>' */
  262. unsigned char    *pointer;    /* where suboption data sits */
  263. int    length;            /* length of suboption data */
  264. {
  265.     register int i;
  266.  
  267.     if (showoptions) {
  268.     if (direction) {
  269.         fprintf(NetTrace, "%s suboption ",
  270.                 (direction == '<')? "Received":"Sent");
  271.         if (length >= 3) {
  272.         register int j;
  273.  
  274.         i = pointer[length-2];
  275.         j = pointer[length-1];
  276.  
  277.         if (i != IAC || j != SE) {
  278.             fprintf(NetTrace, "(terminated by ");
  279.             if (TELOPT_OK(i))
  280.             fprintf(NetTrace, "%s ", TELOPT(i));
  281.             else if (TELCMD_OK(i))
  282.             fprintf(NetTrace, "%s ", TELCMD(i));
  283.             else
  284.             fprintf(NetTrace, "%d ", i);
  285.             if (TELOPT_OK(j))
  286.             fprintf(NetTrace, "%s", TELOPT(j));
  287.             else if (TELCMD_OK(j))
  288.             fprintf(NetTrace, "%s", TELCMD(j));
  289.             else
  290.             fprintf(NetTrace, "%d", j);
  291.             fprintf(NetTrace, ", not IAC SE!) ");
  292.         }
  293.         }
  294.         length -= 2;
  295.     }
  296.     if (length < 1) {
  297.         fprintf(NetTrace, "(Empty suboption???)");
  298.         return;
  299.     }
  300.     switch (pointer[0]) {
  301.     case TELOPT_TTYPE:
  302.         fprintf(NetTrace, "TERMINAL-TYPE ");
  303.         switch (pointer[1]) {
  304.         case TELQUAL_IS:
  305.         fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
  306.         break;
  307.         case TELQUAL_SEND:
  308.         fprintf(NetTrace, "SEND");
  309.         break;
  310.         default:
  311.         fprintf(NetTrace,
  312.                 "- unknown qualifier %d (0x%x).",
  313.                 pointer[1], pointer[1]);
  314.         }
  315.         break;
  316.     case TELOPT_TSPEED:
  317.         fprintf(NetTrace, "TERMINAL-SPEED");
  318.         if (length < 2) {
  319.         fprintf(NetTrace, " (empty suboption???)");
  320.         break;
  321.         }
  322.         switch (pointer[1]) {
  323.         case TELQUAL_IS:
  324.         fprintf(NetTrace, " IS ");
  325.         fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
  326.         break;
  327.         default:
  328.         if (pointer[1] == 1)
  329.             fprintf(NetTrace, " SEND");
  330.         else
  331.             fprintf(NetTrace, " %d (unknown)", pointer[1]);
  332.         for (i = 2; i < length; i++)
  333.             fprintf(NetTrace, " ?%d?", pointer[i]);
  334.         break;
  335.         }
  336.         break;
  337.  
  338.     case TELOPT_LFLOW:
  339.         fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
  340.         if (length < 2) {
  341.         fprintf(NetTrace, " (empty suboption???)");
  342.         break;
  343.         }
  344.         switch (pointer[1]) {
  345.         case 0:
  346.         fprintf(NetTrace, " OFF"); break;
  347.         case 1:
  348.         fprintf(NetTrace, " ON"); break;
  349.         default:
  350.         fprintf(NetTrace, " %d (unknown)", pointer[1]);
  351.         }
  352.         for (i = 2; i < length; i++)
  353.         fprintf(NetTrace, " ?%d?", pointer[i]);
  354.         break;
  355.  
  356.     case TELOPT_NAWS:
  357.         fprintf(NetTrace, "NAWS");
  358.         if (length < 2) {
  359.         fprintf(NetTrace, " (empty suboption???)");
  360.         break;
  361.         }
  362.         if (length == 2) {
  363.         fprintf(NetTrace, " ?%d?", pointer[1]);
  364.         break;
  365.         }
  366.         fprintf(NetTrace, " %d %d (%d)",
  367.         pointer[1], pointer[2],
  368.         (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
  369.         if (length == 4) {
  370.         fprintf(NetTrace, " ?%d?", pointer[3]);
  371.         break;
  372.         }
  373.         fprintf(NetTrace, " %d %d (%d)",
  374.         pointer[3], pointer[4],
  375.         (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
  376.         for (i = 5; i < length; i++)
  377.         fprintf(NetTrace, " ?%d?", pointer[i]);
  378.         break;
  379.  
  380.     case TELOPT_LINEMODE:
  381.         fprintf(NetTrace, "LINEMODE ");
  382.         if (length < 2) {
  383.         fprintf(NetTrace, " (empty suboption???)");
  384.         break;
  385.         }
  386.         switch (pointer[1]) {
  387.         case WILL:
  388.         fprintf(NetTrace, "WILL ");
  389.         goto common;
  390.         case WONT:
  391.         fprintf(NetTrace, "WONT ");
  392.         goto common;
  393.         case DO:
  394.         fprintf(NetTrace, "DO ");
  395.         goto common;
  396.         case DONT:
  397.         fprintf(NetTrace, "DONT ");
  398.         common:
  399.         if (length < 3) {
  400.             fprintf(NetTrace, "(no option???)");
  401.             break;
  402.         }
  403.         switch (pointer[2]) {
  404.         case LM_FORWARDMASK:
  405.             fprintf(NetTrace, "Forward Mask");
  406.             for (i = 3; i < length; i++)
  407.             fprintf(NetTrace, " %x", pointer[i]);
  408.             break;
  409.         default:
  410.             fprintf(NetTrace, "%d (unknown)", pointer[2]);
  411.             for (i = 3; i < length; i++)
  412.             fprintf(NetTrace, " %d", pointer[i]);
  413.             break;
  414.         }
  415.         break;
  416.         
  417.         case LM_SLC:
  418.         fprintf(NetTrace, "SLC");
  419.         for (i = 2; i < length - 2; i += 3) {
  420.             if (pointer[i+SLC_FUNC] <= NSLC)
  421.             fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]);
  422.             else
  423.             fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
  424.             switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
  425.             case SLC_NOSUPPORT:
  426.             fprintf(NetTrace, " NOSUPPORT"); break;
  427.             case SLC_CANTCHANGE:
  428.             fprintf(NetTrace, " CANTCHANGE"); break;
  429.             case SLC_VARIABLE:
  430.             fprintf(NetTrace, " VARIABLE"); break;
  431.             case SLC_DEFAULT:
  432.             fprintf(NetTrace, " DEFAULT"); break;
  433.             }
  434.             fprintf(NetTrace, "%s%s%s",
  435.             pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
  436.             pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
  437.             pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
  438.             if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
  439.                         SLC_FLUSHOUT| SLC_LEVELBITS))
  440.             fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
  441.             fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
  442.             if ((pointer[i+SLC_VALUE] == IAC) &&
  443.             (pointer[i+SLC_VALUE+1] == IAC))
  444.                 i++;
  445.         }
  446.         for (; i < length; i++)
  447.             fprintf(NetTrace, " ?%d?", pointer[i]);
  448.         break;
  449.  
  450.         case LM_MODE:
  451.         fprintf(NetTrace, "MODE ");
  452.         if (length < 3) {
  453.             fprintf(NetTrace, "(no mode???)");
  454.             break;
  455.         }
  456.         {
  457.             char tbuf[64];
  458.             sprintf(tbuf, "%s%s%s%s%s",
  459.             pointer[2]&MODE_EDIT ? "|EDIT" : "",
  460.             pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
  461.             pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
  462.             pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
  463.             pointer[2]&MODE_ACK ? "|ACK" : "");
  464.             fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
  465.         }
  466.         if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK))
  467.             fprintf(NetTrace, " (0x%x)", pointer[2]);
  468.         for (i = 3; i < length; i++)
  469.             fprintf(NetTrace, " ?0x%x?", pointer[i]);
  470.         break;
  471.         default:
  472.         fprintf(NetTrace, "%d (unknown)", pointer[1]);
  473.         for (i = 2; i < length; i++)
  474.             fprintf(NetTrace, " %d", pointer[i]);
  475.         }
  476.         break;
  477.  
  478.     case TELOPT_STATUS: {
  479.         register char *cp;
  480.         register int j, k;
  481.  
  482.         fprintf(NetTrace, "STATUS");
  483.  
  484.         switch (pointer[1]) {
  485.         default:
  486.         if (pointer[1] == TELQUAL_SEND)
  487.             fprintf(NetTrace, " SEND");
  488.         else
  489.             fprintf(NetTrace, " %d (unknown)", pointer[1]);
  490.         for (i = 2; i < length; i++)
  491.             fprintf(NetTrace, " ?%d?", pointer[i]);
  492.         break;
  493.         case TELQUAL_IS:
  494.         if (NetTrace == stdout)
  495.             fprintf(NetTrace, " IS\r\n");
  496.         else
  497.             fprintf(NetTrace, " IS\n");
  498.  
  499.         for (i = 2; i < length; i++) {
  500.             switch(pointer[i]) {
  501.             case DO:    cp = "DO"; goto common2;
  502.             case DONT:    cp = "DONT"; goto common2;
  503.             case WILL:    cp = "WILL"; goto common2;
  504.             case WONT:    cp = "WONT"; goto common2;
  505.             common2:
  506.             i++;
  507.             if (TELOPT_OK((int)pointer[i]))
  508.                 fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
  509.             else
  510.                 fprintf(NetTrace, " %s %d", cp, pointer[i]);
  511.  
  512.             if (NetTrace == stdout)
  513.                 fprintf(NetTrace, "\r\n");
  514.             else
  515.                 fprintf(NetTrace, "\n");
  516.             break;
  517.  
  518.             case SB:
  519.             fprintf(NetTrace, " SB ");
  520.             i++;
  521.             j = k = i;
  522.             while (j < length) {
  523.                 if (pointer[j] == SE) {
  524.                 if (j+1 == length)
  525.                     break;
  526.                 if (pointer[j+1] == SE)
  527.                     j++;
  528.                 else
  529.                     break;
  530.                 }
  531.                 pointer[k++] = pointer[j++];
  532.             }
  533.             printsub(0, &pointer[i], k - i);
  534.             if (i < length) {
  535.                 fprintf(NetTrace, " SE");
  536.                 i = j;
  537.             } else
  538.                 i = j - 1;
  539.  
  540.             if (NetTrace == stdout)
  541.                 fprintf(NetTrace, "\r\n");
  542.             else
  543.                 fprintf(NetTrace, "\n");
  544.  
  545.             break;
  546.                 
  547.             default:
  548.             fprintf(NetTrace, " %d", pointer[i]);
  549.             break;
  550.             }
  551.         }
  552.         break;
  553.         }
  554.         break;
  555.       }
  556.  
  557.     case TELOPT_XDISPLOC:
  558.         fprintf(NetTrace, "X-DISPLAY-LOCATION ");
  559.         switch (pointer[1]) {
  560.         case TELQUAL_IS:
  561.         fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
  562.         break;
  563.         case TELQUAL_SEND:
  564.         fprintf(NetTrace, "SEND");
  565.         break;
  566.         default:
  567.         fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
  568.                 pointer[1], pointer[1]);
  569.         }
  570.         break;
  571.  
  572.     case TELOPT_ENVIRON:
  573.         fprintf(NetTrace, "ENVIRON ");
  574.         switch (pointer[1]) {
  575.         case TELQUAL_IS:
  576.         fprintf(NetTrace, "IS ");
  577.         goto env_common;
  578.         case TELQUAL_SEND:
  579.         fprintf(NetTrace, "SEND ");
  580.         goto env_common;
  581.         case TELQUAL_INFO:
  582.         fprintf(NetTrace, "INFO ");
  583.         env_common:
  584.         {
  585.             register int noquote = 2;
  586.             for (i = 2; i < length; i++ ) {
  587.             switch (pointer[i]) {
  588.             case ENV_VAR:
  589.                 if (pointer[1] == TELQUAL_SEND)
  590.                 goto def_case;
  591.                 fprintf(NetTrace, "\" VAR " + noquote);
  592.                 noquote = 2;
  593.                 break;
  594.  
  595.             case ENV_VALUE:
  596.                 fprintf(NetTrace, "\" VALUE " + noquote);
  597.                 noquote = 2;
  598.                 break;
  599.  
  600.             case ENV_ESC:
  601.                 fprintf(NetTrace, "\" ESC " + noquote);
  602.                 noquote = 2;
  603.                 break;
  604.  
  605.             default:
  606.             def_case:
  607.                 if (isprint(pointer[i]) && pointer[i] != '"') {
  608.                 if (noquote) {
  609.                     putc('"', NetTrace);
  610.                     noquote = 0;
  611.                 }
  612.                 putc(pointer[i], NetTrace);
  613.                 } else {
  614.                 fprintf(NetTrace, "\" %03o " + noquote,
  615.                             pointer[i]);
  616.                 noquote = 2;
  617.                 }
  618.                 break;
  619.             }
  620.             }
  621.             if (!noquote)
  622.             putc('"', NetTrace);
  623.             break;
  624.         }
  625.         }
  626.         break;
  627.  
  628.     default:
  629.         fprintf(NetTrace, "Unknown option ");
  630.         for (i = 0; i < length; i++)
  631.         fprintf(NetTrace, " %d", pointer[i]);
  632.         break;
  633.     }
  634.     if (direction) {
  635.         if (NetTrace == stdout)
  636.         fprintf(NetTrace, "\r\n");
  637.         else
  638.         fprintf(NetTrace, "\n");
  639.     }
  640.     }
  641. }
  642.  
  643. /* EmptyTerminal - called to make sure that the terminal buffer is empty.
  644.  *            Note that we consider the buffer to run all the
  645.  *            way to the kernel (thus the select).
  646.  */
  647.  
  648. void
  649. EmptyTerminal()
  650. {
  651.     if (TTYBYTES() != 0) {
  652.         while (TTYBYTES()) {
  653.         (void) ttyflush(0);
  654.         }
  655.     }
  656. }
  657.  
  658. void
  659. SetForExit()
  660. {
  661.     setconnmode(0);
  662.     do {
  663.     (void)telrcv();            /* Process any incoming data */
  664.     EmptyTerminal();
  665.     } while (ring_full_count(&netiring));    /* While there is any */
  666.     setcommandmode();
  667.     fflush(stdout);
  668.     fflush(stderr);
  669.     setconnmode(0);
  670.     EmptyTerminal();            /* Flush the path to the tty */
  671.     setcommandmode();
  672. }
  673.  
  674. void
  675. Exit(returnCode)
  676. int returnCode;
  677. {
  678.     SetForExit();
  679.     exit(returnCode);
  680. }
  681.  
  682. void
  683. ExitString(string, returnCode)
  684. char *string;
  685. int returnCode;
  686. {
  687.     SetForExit();
  688.     fwrite(string, 1, strlen(string), stderr);
  689.     exit(returnCode);
  690. }
  691.  
  692. void sleep(secs)
  693. int secs;
  694. {    Delay(50*secs);
  695. }
  696.